home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n06.arc
/
XBUF.C
< prev
next >
Wrap
Text File
|
1991-03-06
|
3KB
|
145 lines
// xbuf.C - Extends BIOS keystroke buffer.
#include <alloc.H>
#include <dos.H>
#include "xbuf.H"
// installation Flag
static int installed = 0;
// Queue Variables
static int *q;
static int qsize;
static int head, tail;
// Miscellaneous
#define ZERO_FLAG 64
union REGS r;
static void interrupt (*Old_Timer_Int)(void);
// Function Prototypes
int c_break(void);
int keypress(void);
void interrupt New_Timer_Int(void);
/* A replacement for Control-break processing, this function is
installed via ctrlbrk(). It returns 1 to indicate that breaks
are to be ignored. "^C" is still displayed.
*/
static int c_break(void)
{
return 1;
}
/* Returns the next key from the queue. Returns 0 if xbuf has not
been installed.
*/
int getkey(void)
{
int key;
if(!installed)
return 0;
while(!iskey())
;
disable ();
key = q[head = (head + 1) % qsize];
enable ();
return key;
}
/* Returns non-zero if a keystroke is present in the xbuf buffer,
or returns 0 if none are present or xbuf has not been installed.
*/
int iskey(void)
{
int flag;
if(!installed)
return 0;
disable();
flag = head != tail;
enable();
return flag;
}
/* Returns non-zero if one or more keystrokes are present in the BIOS
key buffer, or returns zero.
*/
static int keypress(void)
{
r.h.ah = 1;
int86(0x16, &r, &r);
return (r.x.flags & ZERO_FLAG) ? 0 : 1;
}
/* Replacement for the timer interrupt. With every 'tick' of the timer,
it calls the old timer interrupt, then, checks the BIOS key buffer
for keystrokes. Each keystroke is placed in the xbuf buffer.
*/
static void interrupt New_Timer_Int(void)
{
register keystroke, temp;
(*Old_Timer_Int)();
if(keypress())
{
_AH = 0; /* Get keystroke */
geninterrupt(0x16);
keystroke = _AX;
if(keystroke & 0x00ff)
keystroke &= 0x00ff;
if((temp = (tail + 1) % qsize) == head)
return; /* Exit if queue full */
q[tail = temp] = keystroke;
}
}
/* Installs xbuf buffer.
To install: xbuf_install(bufsize);
buffer size must be 255 or less
returns either ERROR or OK
*/
int xbuf_install(int size)
{
if(installed)
return ERROR;
if((qsize = size) < DEFAULT_SIZE || qsize > 255)
return ERROR;
if((q = (int *)malloc(qsize * sizeof(int))) == NULL)
return ERROR;
qsize++; // Circular queues are one element larger
head = tail = 0;
ctrlbrk(c_break);
Old_Timer_Int = getvect(0x1c);
setvect(0x1c, New_Timer_Int);
installed = 1;
return OK;
}
/* removes xbuf buffer
returns either ERROR or OK
*/
int xbuf_remove(void)
{
if(!installed)
return ERROR;
setvect(0x1c, Old_Timer_Int);
installed = 0;
return OK;
}